//package com.haruhi.ws.client;
//
//import com.haruhi.event.Message;
//import com.haruhi.event.MessageQueue;
//import com.haruhi.ws.Endpoint;
//
//import javax.websocket.ClientEndpointConfig;
//import javax.websocket.CloseReason;
//import javax.websocket.ContainerProvider;
//import javax.websocket.EndpointConfig;
//import javax.websocket.Session;
//import javax.websocket.WebSocketContainer;
//import java.io.IOException;
//import java.net.URI;
//import java.net.URISyntaxException;
//import java.util.Collections;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.Callable;
//import java.util.concurrent.Future;
//import java.util.concurrent.FutureTask;
//import java.util.concurrent.atomic.AtomicBoolean;
//
//public class ClientEndpoint implements Endpoint {
//
//    private static final WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer();
//
//    private Session session;
//    private final URI uri;
//    private final ClientEndpointConfig configurator;
//    private long reconnectPeriod;
//    private final ClientEndpointAdapter adapter;
//    private final AtomicBoolean connecting = new AtomicBoolean(false);
//
//    public Session getSession() {
//        return session;
//    }
//
//    public URI getUri() {
//        return uri;
//    }
//
//    public ClientEndpointConfig getConfigurator() {
//        return configurator;
//    }
//
//    public long getReconnectPeriod() {
//        return reconnectPeriod;
//    }
//
//    public ClientEndpointAdapter getAdapter() {
//        return adapter;
//    }
//
//    public AtomicBoolean getConnecting() {
//        return connecting;
//    }
//
//
//    private ClientEndpoint(URI url, ClientEndpointConfig configurator, long reconnectPeriod, Endpoint handler) {
//        this.uri = url;
//        this.configurator = configurator;
//        this.reconnectPeriod = reconnectPeriod;
//        this.adapter = new ClientEndpointAdapter(handler == null ? this : handler);
//    }
//
//
//    /**
//     *
//     * @param url
//     * @param handshakeHeaders
//     * @param reconnectPeriod 若发生断连 重连间隔时长 单位毫秒
//     * @return
//     * @throws URISyntaxException
//     */
//    public static ClientEndpoint create(String url, Map<String,String> handshakeHeaders, long reconnectPeriod) throws URISyntaxException {
//        return create(url,handshakeHeaders,reconnectPeriod,null);
//    }
//
//    /**
//     * 自定义一个Endpoint
//     * @param url
//     * @param handshakeHeaders
//     * @param handler
//     * @return
//     * @throws URISyntaxException
//     */
//    public static <T extends Endpoint> ClientEndpoint create(String url, Map<String,String> handshakeHeaders, Endpoint handler) throws URISyntaxException {
//        return create(url,handshakeHeaders,2500L,handler);
//    }
//
//    private static <T extends Endpoint> ClientEndpoint create(String url, Map<String,String> handshakeHeaders, long reconnectPeriod, Endpoint handler) throws URISyntaxException {
//        return new ClientEndpoint(new URI(url),ClientEndpointConfig.Builder.create().configurator(new ClientEndpointConfig.Configurator(){
//            @Override
//            public void beforeRequest(Map<String, List<String>> headers) {
//                if (handshakeHeaders != null && !handshakeHeaders.isEmpty()) {
//                    handshakeHeaders.forEach((k,v) ->{
//                        headers.put(k, Collections.singletonList(v));
//                    });
//                }
//
//            }
//        }).build(),reconnectPeriod,handler);
//    }
//
//    /**
//     *
//     * @param autoReConnect 若连接失败 是否自动开启重连
//     * @return 返回true表示连接成功
//     */
//    public synchronized boolean connect(boolean autoReConnect) {
//        try {
//            if(session == null){
//                session = webSocketContainer.connectToServer(adapter, configurator,uri);
//            }
//            return true;
//        } catch (Exception e){
//            // 连接失败
////            System.out.println("连接失败");
//            if(autoReConnect) {
//                reConnect();
//            }
//            return false;
//        }
//    }
//
//
//    /**
//     * 重连
//     * @return
//     */
//    public synchronized Future<Boolean> reConnect(){
//        if(!connecting.get()){
//            connecting.set(true);
//            // 开始重连
//            Callable<Boolean> callable = () -> {
//                close();
//                while (true) {
//                    if (connect(false)) {
//                        connecting.set(false);
//                        return true;
//                    } else {
//                        try {
//                            Thread.sleep(reconnectPeriod);
//                        } catch (InterruptedException e) {
//                            // 如果线程被标记为中断 会走这里 然后就能结束这个线程
//                            return false;
//                        }
//                    }
//                }
//            };
//            FutureTask<Boolean> reConnectFutureTask = new FutureTask<>(callable);
//            Thread thread = new Thread(reConnectFutureTask);
//            thread.start();
//
//            return reConnectFutureTask;
//        }
//
//        // 直接返回false表示重连任务已经在执行中了
//        FutureTask<Boolean> booleanFutureTask = new FutureTask<>(() -> false);
//        Thread thread = new Thread(booleanFutureTask);
//        thread.start();
//        return booleanFutureTask;
//    }
//    public synchronized void close(){
//        if (this.session != null) {
//            if (this.session.isOpen()) {
//                try {
//                    this.session.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//            this.session = null;
//        }
//    }
//
//    @Override
//    public void onOpen(Session session, EndpointConfig endpointConfig) {
//        // 连接成功
////        System.out.println("连接成功");
//    }
//
//
//    @Override
//    public void onMessage(Session session, String msg){
//        MessageQueue.offer(new Message(session,msg));
//    }
//
//    @Override
//    public void onClose(Session session, CloseReason closeReason) {
//        reConnect();
//    }
//
//    @Override
//    public void onError(Session session, Throwable throwable) {
//        reConnect();
//    }
//}
